package com.nd.android.musicboxlibrary.business.comm;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.text.TextUtils;

import com.common.StarAppConfig;
import com.common.StarAppConst;
import com.nd.android.musicboxlibrary.business.bean.Album;
import com.nd.android.musicboxlibrary.business.bean.MusicInfo;
import com.nd.android.musicboxlibrary.business.db.dao.DbManager;
import com.nd.android.musicboxlibrary.interf.ManagerFactory;
import com.nd.android.musicboxlibrary.ui.common.ImageLoaderUtil;
import com.nd.android.musicboxlibrary.util.ConfigHelper;
import com.nd.android.musicboxlibrary.util.Log;
import com.nd.android.musicboxlibrary.util.MusicBoxUtils;
import com.product.android.business.ApplicationVariable;
import com.product.android.business.config.Configuration;
import com.product.android.commonInterface.allCommonInterfaceImpl.AllCommonCallOtherModel;
import com.product.android.utils.LogUtils;

/**
 * 底层业务封装
 *
 * @author 慕容秋 (muroqiu@qq.com)
 */
public final class ApiManager {

    // 文件服务器地址
    public static final String URL_FILE = 
            StarAppConfig.getConfig(StarAppConfig.FILE_STORAGE_SYSTEM_SERVICE);
    // 明星APP API服务器地址
//    public static final String URL_STARAPP = "http://u.starapp.99.com";
      public static final String URL_STARAPP = 
              StarAppConfig.getConfig(StarAppConfig.MIDDLE_LAYER_FAN_GROUP_SERVICE_KEY);

    public static final String CLOUDID_VALUE = Configuration.CLOUNDID;
    public static final String APPID_VALUE = Configuration.OAP_APPID+"";
    public static final String APIKEY_VALUE =  StarAppConfig.getConfig(StarAppConfig.CONFIG_API_KEY);


	private String mSid = "";
	private static final String mType = "3";
	private static final String mId = "1";
	private static final String mPath = "/music";
	private static final int SIZE_BATCH = 100;
	public static final String URL_ALBUM = URL_FILE + "folders/list";
	public static final String URL_MUSIC = URL_FILE + "files/list";
	public static final String URL_MUSIC_INFO = URL_FILE + "files/info";
	public static final String URL_MUSIC_FAV_SET = URL_STARAPP + "mg/api/aid/modi_fav_song?sid=";
	public static final String URL_MUSIC_FAV_GET = URL_STARAPP + "mg/api/aid/favorite_song_list?pos=150&sid=";
	public static final String URL_MUSIC_POST_FID = URL_STARAPP + "mg/api/aid/music_commit";

    private static final String YEAR_TEMPLE = "年代： %s年";
    private static ApiManager instance = null;

    private Context mContext;

    private DbManager dbManager;

    /**
     * 获取 ApiManager 实例 <br>
     * Created 2014年9月16日 上午12:17:29
     * 
     * @param context
     *            上下文句柄
     * @return ApiManager
     * @author 慕容秋
     */
    public static ApiManager getInstance(Context context) {
        if (instance == null) {
            ImageLoaderUtil.initImageLoader(context);
            instance = new ApiManager(context);
        }
        return instance;
    }

    /**
     * Creates a new instance of ApiManager. <br>
     * Created 2014年9月16日 上午12:17:33
     * 
     * @param context
     *            上下文句柄
     */
    private ApiManager(Context context) {
        mContext = context;
    }

    /**
     * 初始化sid, uid数据 <br>
     * Created 2014年9月16日 上午12:17:35
     * 
     * @param sid
     *            SessionID
     * @param uid
     *            用户ID
     * @author 慕容秋
     */
    public void init(String sid, String uid) {

        if (!mSid.equals(sid)) {
            mSid = sid;
            ConfigHelper.getInstance(mContext).saveKey(ConfigHelper.CONFIG_KEY_SID, sid);
        }

        String uid_cache = ConfigHelper.getInstance(mContext).loadKey(ConfigHelper.CONFIG_KEY_UID);
        if (!uid_cache.equals(uid)) {
            ConfigHelper.getInstance(mContext).saveKey(ConfigHelper.CONFIG_KEY_UID, uid);
            if (dbManager != null) {
                dbManager.closeDB();
            }
        }
        dbManager = DbManager.getInstance(mContext, uid);
    }

    /**
     * 获取 DbManager 对象 <br>
     * Created 2014年9月16日 上午12:17:
     * 
     * @return DbManager
     * @author 慕容秋
     */
    public DbManager getDb() {
        String uid = ConfigHelper.getInstance(mContext).loadKey(ConfigHelper.CONFIG_KEY_UID);
        dbManager = DbManager.getInstance(mContext, uid);
        return dbManager;
    }

    /**
     * 关闭 DbManager 对象 <br>
     * Created 2014年9月16日 上午12:17:41
     * 
     * @author 慕容秋
     */
    public void closeDb() {
        if (dbManager != null) {
            dbManager.closeDB();
        }
    }

    /**
     * 获取缓存Sid <br>
     * Created 2014年9月16日 上午12:17:44
     * 
     * @return String
     * @author 慕容秋
     */
    private String getSid() {
        if (TextUtils.isEmpty(mSid)) {
           mSid = ConfigHelper.getInstance(mContext).loadKey(ConfigHelper.CONFIG_KEY_SID);
           if (TextUtils.isEmpty(mSid)) {
        	   mSid = ApplicationVariable.INSTANCE.getLocalSid();   
           }
           if (TextUtils.isEmpty(mSid)) {
        	   mSid = AllCommonCallOtherModel.MainModel.getRelginSid();        	   
           }
        }

        return mSid;
    }

    /**
     * 生成Header <br>
     * Created 2014年9月16日 上午12:17:44
     * 
     * @return HashMap<String, String>
     */
    public HashMap<String, String> getHeader() {
        HashMap<String, String> headerMap = new HashMap<String, String>();
        // headerMap.put("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4");

        headerMap.put("CLOUDID", CLOUDID_VALUE);
        headerMap.put("CUID", "" + ApplicationVariable.INSTANCE.getUapUid());
        headerMap.put("CLIENTTYPE", "Android");
        headerMap.put("APPID", APPID_VALUE);
        headerMap.put("APIKEY", APIKEY_VALUE);
        if (!TextUtils.isEmpty(getSid())) {
            headerMap.put("SID", getSid());
        }

        Log.d(headerMap.toString());

        return headerMap;
    }

    /**
     * 获取音乐专辑列表 <br>
     * Created 2014年9月16日 上午12:17:44
     * 
     * @return 专辑列表
     * @throws NdException Exception
     */
    public List<Album> getAlbumList() throws NdException {
        List<Album> result = new ArrayList<Album>();

        List<Album> albumList = getAlbumList(Long.MAX_VALUE);
        result.addAll(albumList);
        while (albumList.size() == SIZE_BATCH) {
            // 有更多数据
            albumList = getAlbumList(albumList.get(SIZE_BATCH - 1).getId());
            if (!albumList.isEmpty()) {
                result.addAll(albumList);
            }
        }

        return result;
    }

    /**
     * 获取音乐专辑列表 <br>
     * Created 2014年9月16日 上午12:17:44
     * 
     * @param idMax
     *            最大id值
     * @return 专辑列表
     * @throws NdException Exception
     */
    private List<Album> getAlbumList(long idMax) throws NdException {
        List<Album> result = new ArrayList<Album>();

        String url = URL_ALBUM;
        JSONObject jsonParams = new JSONObject();
        try {
            jsonParams.put("type", mType);
            jsonParams.put("id", mId);
            jsonParams.put("path", mPath);
            jsonParams.put("id_max", idMax + "");
            jsonParams.put("sid", getSid());
            jsonParams.put("page_size", SIZE_BATCH);

            String response = HttpTool_Base.post(url, jsonParams, getHeader());

            JSONArray jsonArrayOfFile = new JSONArray(response);
            int size = jsonArrayOfFile.length();
            for (int i = 0; i < size; i++) {
                Album album = new Album();
                JSONObject jsonObjectOfFile = jsonArrayOfFile.getJSONObject(i);
                album.setId(jsonObjectOfFile.optLong("folderid"));

                JSONObject jsonObjectOfInfo = jsonObjectOfFile.optJSONObject("info");
                if (jsonObjectOfInfo != null) {
                    album.setName(jsonObjectOfInfo.optString("name"));
                    String year = YEAR_TEMPLE;
                    album.setDesc(String.format(year,
                            MusicBoxUtils.formatDateToYear(jsonObjectOfInfo.optLong("time"))));
                    album.setBgFid(jsonObjectOfInfo.optLong("cover_id"));
                }

                result.add(album);
            }

        } catch (NdException e) {
            if (e.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                // SID 无效
                // 取到最新的sid，然后判断这个sid是否为空，不为空就替换当前sid，再重调接口
                String sid = AllCommonCallOtherModel.MainModel.getRelginSid();
                if (!TextUtils.isEmpty(sid)) {
                    mSid = sid;
                    ConfigHelper.getInstance(mContext).saveKey(ConfigHelper.CONFIG_KEY_SID, mSid);
                    return getAlbumList(idMax);
                } else {
                    throw e;
                }
            } else {
                throw e;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new NdException(e);
        }

        return result;
    }

    /**
     * 获取单曲列表 <br>
     * Created 2014年9月16日 上午12:17:44
     * 
     * @return List<MusicInfo>
     * @throws NdException Exception
     */
    public List<MusicInfo> getMusicList() throws NdException {
        List<MusicInfo> result = new ArrayList<MusicInfo>();

        // 先获取服务器我喜欢数据
        HashMap<String, String> favFidList = null;
        try {
            favFidList = getMusicListOfFav();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //每次调用最多服务器给100个数据
        List<MusicInfo> musicInfoList = getMusicList(Long.MAX_VALUE, favFidList);
        result.addAll(musicInfoList);
        while (musicInfoList.size() == SIZE_BATCH) {
            // 有更多数据
            musicInfoList = getMusicList(musicInfoList.get(SIZE_BATCH - 1).getId(), favFidList);
            if (!musicInfoList.isEmpty()) {
                result.addAll(musicInfoList);
            }
        }

        return result;
    }

    /**
     * 获取单曲列表 -- 内部函数 <br>
     * Created 2014年9月16日 上午12:17:46
     * 
     * @param idMax
     *            最大ID值
     * @param favFidList
     *            喜欢的音乐列表
     * @return List<MusicInfo>
     * @throws NdException Exception
     * @author 慕容秋
     */
    private List<MusicInfo> getMusicList(long idMax, HashMap<String, String> favFidList)
            throws NdException {
        List<MusicInfo> result = new ArrayList<MusicInfo>();

        String url = URL_MUSIC;
        JSONObject jsonParams = new JSONObject();
        try {
            jsonParams.put("type", mType);
            jsonParams.put("id", mId);
            jsonParams.put("path", mPath);
            jsonParams.put("id_max", idMax + "");
            jsonParams.put("sid", getSid());
            jsonParams.put("show", "1");
            jsonParams.put("page_size", SIZE_BATCH);

            String response = HttpTool_Base.post(url, jsonParams, getHeader());

			JSONArray jsonArrayOfFile = new JSONArray(response);
			int size = jsonArrayOfFile.length();
			for (int i = 0; i < size; i++) {
				MusicInfo musicInfo = new MusicInfo();
				JSONObject jsonObjectOfFile = jsonArrayOfFile.getJSONObject(i);
				musicInfo.setId(jsonObjectOfFile.optLong("fid"));
				musicInfo.setSize(jsonObjectOfFile.optInt("size"));
				musicInfo.setHQSize(jsonObjectOfFile.optInt("hq_size"));// by jiangwb 2014-11-18 10:53
				musicInfo.setAlbumId(jsonObjectOfFile.optLong("folderid"));

				JSONObject jsonObjectOfInfo = jsonObjectOfFile.optJSONObject("info");
				if (jsonObjectOfInfo != null) {
					musicInfo.setMusicName(jsonObjectOfInfo.optString("song_name"));
					musicInfo.setLrcId(jsonObjectOfInfo.optLong("lrc_fid"));
                    // by jiangwb 默认播放都是非HQ的，只有VIP用户下载了HQ的才需要显示HQ图标，而且不需要通过服务器来配置
                    if(!StarAppConfig.getBooleanConfig(StarAppConfig.CONFIG_VERSION1_8)){
                        musicInfo.setHQ(jsonObjectOfInfo.optString("hq").equals("0"));
                    }
					musicInfo.setHasMv(jsonObjectOfInfo.optString("mv").equals("0"));
					musicInfo.setTime(jsonObjectOfInfo.optString("time"));
				}
				if (favFidList != null && favFidList.containsKey(musicInfo.getId() + "")) {
					musicInfo.setFaved(true);
					Log.d(musicInfo.getId() + "");
				}
				if(StarAppConfig.getBooleanConfig(StarAppConfig.CONFIG_VERSION1_8)){
					getMusicInfo(musicInfo);//by jiangwb					
				}
				result.add(musicInfo);
			}

            ManagerFactory.getDownloadInstance(mContext).batchAddLrc2DownloadList(result);
            ConfigHelper.getInstance(mContext).saveBooleanKey(ConfigHelper.CONFIG_LRC_UTF, true);
        } catch (NdException e) {
            if (e.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                // SID 无效
                // 取到最新的sid，然后判断这个sid是否为空，不为空就替换当前sid，再重调接口

                String sid = AllCommonCallOtherModel.MainModel.getRelginSid();
                if (!TextUtils.isEmpty(sid)) {
                    mSid = sid;
                    ConfigHelper.getInstance(mContext).saveKey(ConfigHelper.CONFIG_KEY_SID, mSid);
                    return getMusicList(idMax, favFidList);
                } else {
                    throw e;
                }
            } else {
                throw e;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new NdException(e);
        }

        return result;
    }

	/**
	 * 获取音乐文件的详情信息
	 * <br>
	 * Created 2014年11月19日 上午16:58:46
	 *
	 * @param idArray 待操作的音乐文件ID列表
	 * @return 操作提示
	 * @throws NdException
	 * @author jiangwb
	 */
	public void getMusicInfo(MusicInfo musicInfo) throws NdException{
		String info_url = URL_MUSIC_INFO  
				+ "/fid/"+musicInfo.getId()
				+"/type/"+mType 
				+"/sid/" +getSid()
				+"/id/" + mId;
		try {
			HashMap<String, String> headMap = new HashMap<String, String>();
			headMap.put("CLOUDID", CLOUDID_VALUE);
			headMap.put("APPID", APPID_VALUE);
			String response = HttpTool_Base.get(info_url , headMap);
			JSONObject jsonObjectOfFile = new JSONObject(response);
			JSONObject jsonObjectOfInfo = jsonObjectOfFile.optJSONObject("info");
			if (jsonObjectOfInfo != null) {
				long hq_fid = jsonObjectOfInfo.optLong("hq_fid");
				LogUtils.d("ApiManager.java -- jiangwb", "hq_fid" + hq_fid);
				musicInfo.setHQId(hq_fid);
				if(musicInfo != null && hq_fid > 0){
					getHQMusicInfo(musicInfo);
				}
			}
			LogUtils.e("ApiManager.java -- jiangwb", "info_url:" + info_url);
		} catch (Exception e) {
			LogUtils.e("ApiManager.java -- jiangwb", "",e);
		}
	}

	/**
	 * 获取高清音乐文件的详情信息
	 * <br>
	 * Created 2014年11月19日 上午16:58:46
	 *
	 * @param idArray 待操作的音乐文件ID列表
	 * @return 操作提示
	 * @throws NdException
	 * @author jiangwb
	 */
	public void getHQMusicInfo(MusicInfo musicInfo) throws NdException{
		String info_url = URL_MUSIC_INFO  
				+ "/fid/"+musicInfo.getHQId()
				+"/type/"+mType 
				+"/sid/" +getSid()
				+"/id/" + mId;
		try {
			HashMap<String, String> headMap = new HashMap<String, String>();
			headMap.put("CLOUDID", CLOUDID_VALUE);
			headMap.put("APPID", APPID_VALUE);
			String response = HttpTool_Base.get(info_url , headMap);
			/*
			 * {"flag":1,"expire_time":0,"local":"","ip":"10.31.243.62","time":1416368218087,
			 * "hits":1,"info":"","name":"20141119113657164","height":0,"width":0,"size":9612121,
			 * "ext":"mp3","sort":"audio","mime":"audio/mpeg",
			 * "md5":"2ce5ad8a25bef4e2e5489d5404fc08b2","path":"/music_hq/46398.mp3",
			 * "root":"starapp/3/1/233","uid":0,"folderid":8446,"fid":46398}
			 */

			JSONObject jsonObjectOfFile = new JSONObject(response);
			if (jsonObjectOfFile != null) {
				long hq_size = jsonObjectOfFile.optLong("size");
				musicInfo.setHQSize(hq_size);
				LogUtils.d("ApiManager.java -- jiangwb", "hq_size" + hq_size);
			}
			LogUtils.e("ApiManager.java -- jiangwb", "info_url:" + info_url);
		} catch (Exception e) {
			LogUtils.e("ApiManager.java -- jiangwb", "",e);
		}
	}


	/**
	 * 批量置为喜欢操作
	 * <br>
	 * Created 2014年9月16日 上午12:17:46
	 *
	 * @param idArray 待操作的音乐文件ID列表
	 * @return 操作提示
	 * @throws NdException
	 */
	public String setMusicListFav(Long[] idArray) throws NdException {
		return setMusicListFav(idArray, true);
	}

    /**
     * 单笔修改喜欢标识 <br>
     * Created 2014年9月16日 上午12:17:46
     * 
     * @param id
     *            音乐文件ID
     * @param isFav
     *            是否喜欢
     * @return 操作提示
     * @throws NdException Exception
     */
    public String setMusicFav(long id, boolean isFav) throws NdException {
        Long[] param = new Long[1];
        param[0] = id;

        return setMusicListFav(param, isFav);
    }

    /**
     * 修改喜欢标识 <br>
     * Created 2014年9月16日 上午12:17:46
     * 
     * @param idArray
     *            待操作的音乐文件ID列表
     * @param isFav
     *            是否喜欢
     * @return 操作提示
     * @throws NdException Exception
     */
    private String setMusicListFav(Long[] idArray, boolean isFav) throws NdException {
        String result = "sucess";

        String url = URL_MUSIC_FAV_SET + getSid();
        JSONObject jsonParams = new JSONObject();
        try {
            JSONArray jsonArray = new JSONArray();
            for (long id : idArray) {
                jsonArray.put(id);
            }

            jsonParams.put("mid", jsonArray);
            if (isFav) {
                jsonParams.put("oper", 1);
            } else {
                jsonParams.put("oper", 0);
            }

            result = HttpTool_Base.post(url, jsonParams, getHeader());
        } catch (NdException e) {
            if (e.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                // SID 无效
                // 取到最新的sid，然后判断这个sid是否为空，不为空就替换当前sid，再重调接口

                String sid = AllCommonCallOtherModel.MainModel.getRelginSid();
                if (!TextUtils.isEmpty(sid)) {
                    mSid = sid;
                    ConfigHelper.getInstance(mContext).saveKey(ConfigHelper.CONFIG_KEY_SID, mSid);
                    return setMusicListFav(idArray, isFav);
                } else {
                    throw e;
                }
            } else {
                throw e;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new NdException(e);
        }

        return result;
    }

    /**
     * 增量获取我喜欢的歌曲列表 <br>
     * Created 2014年9月16日 上午12:17:46
     * 
     * @return 音乐列表
     * @throws NdException Exception
     */
    public HashMap<String, String> getMusicListOfFav() throws NdException {

        HashMap<String, String> result = new HashMap<String, String>();
        String url = URL_MUSIC_FAV_GET + getSid();
        try {
            String response = HttpTool_Base.get(url, getHeader());

            JSONObject jsonResponse = new JSONObject(response);
            if (jsonResponse != null && jsonResponse.optJSONArray("musiclist") != null) {
                JSONArray jsonArrayOfFile = jsonResponse.optJSONArray("musiclist");
                int size = jsonArrayOfFile.length();
                for (int i = 0; i < size; i++) {
                    JSONObject jsonObjectOfFile = jsonArrayOfFile.getJSONObject(i);

                    result.put(jsonObjectOfFile.optString("song_fid"),
                            jsonObjectOfFile.optString("song_fid"));
                }
            }
        } catch (NdException e) {
            if (e.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                // SID 无效
                // 取到最新的sid，然后判断这个sid是否为空，不为空就替换当前sid，再重调接口

                String sid = AllCommonCallOtherModel.MainModel.getRelginSid();
                if (!TextUtils.isEmpty(sid)) {
                    mSid = sid;
                    ConfigHelper.getInstance(mContext).saveKey(ConfigHelper.CONFIG_KEY_SID, mSid);
                    return getMusicListOfFav();
                } else {
                    throw e;
                }
            } else {
                throw e;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new NdException(e);
        }

        return result;
    }

    /**
     * <br>
     * Created 2014年11月8日 下午11:30:35
     * 
     * @param musicInfo MusicInfo
     * @return String
     * @throws NdException Exception
     * @author wat.ztag
     */
    public String postPlayingID(MusicInfo musicInfo) throws NdException {
        String result = "0";

        String url = URL_MUSIC_POST_FID;
        JSONObject jsonParams = new JSONObject();
        try {
            jsonParams.put("fid", musicInfo.getId());
            result = HttpTool_Base.post(url, jsonParams, getHeader());
        } catch (NdException e) {
            if (e.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                // SID 无效
                // 取到最新的sid，然后判断这个sid是否为空，不为空就替换当前sid，再重调接口

                String sid = AllCommonCallOtherModel.MainModel.getRelginSid();
                if (!TextUtils.isEmpty(sid)) {
                    mSid = sid;
                    ConfigHelper.getInstance(mContext).saveKey(ConfigHelper.CONFIG_KEY_SID, mSid);
                    return postPlayingID(musicInfo);
                } else {
                    throw e;
                }
            } else {
                throw e;
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new NdException(e);
        }

        return result;
    }

    /**
     * <br>
     * Created 2014年11月8日 下午11:30:35
     * 
     * @param musicInfo
     * @return String
     * @throws NdException Exception
     * @author wat.ztag
     */
    public String getTestSid() throws NdException {
        String result = "0";

        String url = "http://loginuap.99.com/login/ticket";
        JSONObject jsonParams = new JSONObject();
        try {
            jsonParams.put("appid", "233");
            jsonParams.put("blowfish", "99888111111111111kk0034001");
            jsonParams.put("ticket", "f6160f596ebf3825713e7fd0f03ed6d7");
            jsonParams.put("tag", "1");
            result = HttpTool_Base.post(url, jsonParams, getHeader());
        } catch (Exception e) {
            e.printStackTrace();
            throw new NdException(e);
        }

        return result;
    }
}
